package com.ice.work.moment.facade.user.filter;

import cn.hutool.core.map.MapUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.google.common.collect.Lists;
import com.honeybee.cloud.framework.common.enums.AuthEnum;
import com.honeybee.cloud.framework.common.enums.DataStatusEnum;
import com.honeybee.cloud.framework.common.enums.DeprecatedEnum;
import com.honeybee.cloud.framework.common.enums.MethodTypeEnum;
import com.ice.work.moment.facade.user.model.Resource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;

import java.beans.Transient;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * @Description
 * @Author DELL
 * @Create 2019-02-15
 * @Since 1.0.0
 */
@Slf4j
@Data
public abstract class AbstractResourceFilter implements Serializable {

    protected List<Resource> getResources(Map<RequestMappingInfo, HandlerMethod> requestMappingInfoMap) {
        List<Resource> resourceList = Lists.newArrayList();
        if (MapUtil.isEmpty(requestMappingInfoMap)) {
            return resourceList;
        }
        for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : requestMappingInfoMap.entrySet()) {
            RequestMappingInfo mappingInfo = entry.getKey();
            HandlerMethod handlerMethod = entry.getValue();
            for (String path : mappingInfo.getPatternsCondition().getPatterns()) {
                for (RequestMethod method : mappingInfo.getMethodsCondition().getMethods()) {
                    try {
                        if (handlerMethod.hasMethodAnnotation(Transient.class)) {
                            continue;
                        }
                        MethodTypeEnum methodTypeEnum = MethodTypeEnum.valueOf(method.name());
                        Resource resource = new Resource();
                        resource.setName(mappingInfo.getName());
                        resource.setMethod(methodTypeEnum.value());
                        resource.setPath(path);
                        resource.setSign(DigestUtil.md5Hex(path));
                        if (handlerMethod.hasMethodAnnotation(Deprecated.class)) {
                            resource.setDeprecated(DeprecatedEnum.YES.getValue());
                        } else {
                            resource.setDeprecated(DeprecatedEnum.NO.getValue());
                        }
                        PreAuthorize authorization = handlerMethod.getMethodAnnotation(PreAuthorize.class);
                        if (authorization == null) {
                            resource.setAuth(AuthEnum.NO.value());
                        } else {
                            resource.setAuth(AuthEnum.YES.value());
                            String value = authorization.value();
                            resource.setCode(value.substring(value.indexOf("'") + 1, value.lastIndexOf("'")));
                        }
                        resource.setDataStatus(DataStatusEnum.VALID.key);
                        resourceList.add(resource);

                    } catch (IllegalArgumentException e) {
                        log.error("资源处理异常", e);
                    }
                }
            }
        }
        return resourceList;
    }

}
